home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 121_01 / local.c < prev    next >
Text File  |  1985-08-19  |  12KB  |  524 lines

  1. /*
  2. HEADER: CUG 121.??;
  3.  
  4.     TITLE:    local - misc functions used on this disk;
  5.     VERSION:    1.0;
  6.     DATE:    12/01/85;
  7.     DESCRIPTION: "This file contains functions used by call.c, if.c, tel.c
  8.         and tl370.c.  The following functions are included:
  9.         abort(), barf(), sign(), stacktop(), strncat(), strncmp(),
  10.         strncpy(), strlower(), strupper(), strindex(), index(),
  11.         findline(), getdph(), extract(), mputs(), mputc(), moready(),
  12.         mgetc(), miready(), hayesput(), hayesget(), globarg(),
  13.         posarg()";
  14.     KEYWORDS:    functions;
  15.     SYSTEM:    CP/M;
  16.     FILENAME:    LOCAL.C;
  17.     WARNINGS:    "This file contains some functions that are not used by
  18.         anything on this disk, but may be of general interest or use.";
  19.     AUTHORS:    Mike W. Meyer, Steve Kenton;
  20.     COMPILERS:    BDS-C 1.50;
  21. */
  22. /*
  23.  * local.c - the local library of C functions for BDS C.
  24.  *    copyright (c) 1981, Mike Meyer
  25.  *    parts copyright (c) 1982, Steve Kenton
  26.  *        modified stylewise to fit my conventions - mwm
  27.  *
  28.  *    modified by rfb (Dec '85) -
  29.  *        changed modem i/o to use v1.50 #defines, added mgetc()
  30.  *        changed stacktop() to use topofmem()
  31.  *        modified style & made it consistent throughout (apologies to
  32.  *        anyone offended)
  33.  *        added #include for v1.50 hardware values
  34.  */
  35.  
  36. #include <bdscio.h>
  37. #include <hardware.h>
  38. #include "local.h"
  39.  
  40. /*
  41.  * barf - exit with a non-zero value, possible printing a message
  42.  */
  43. barf(chuck)
  44. char *chuck;
  45. {
  46.     abort(chuck);
  47. }
  48.  
  49. /*
  50.  * abort - the real body of barf, used by the squeamish.
  51.  */
  52. abort(charles)
  53. char *charles;
  54. {
  55.     if (charles)
  56.         puts(charles);
  57.     exit(1);
  58. }
  59.  
  60. /*
  61.  * sign - return 0, 1, -1 depending on the sign of x
  62.  */
  63. int sign(x)
  64. {
  65.     return (x > 0) - (x < 0);
  66. }
  67.  
  68. /*
  69.  * stacktop - just returns address of the top of the stack.
  70.  *    uses v1.50 function topofmem()
  71.  */
  72. char *stacktop()
  73. {
  74.     return topofmem();
  75. }
  76.  
  77. /*
  78.  *    strncpy - copy a substring up to N characters long
  79.  */
  80. strncpy(str1, str2, n)
  81. char *str1, *str2;
  82. unsigned n;
  83. {
  84.     while (n-- && *str2)
  85.         *str1++ = *str2++;
  86.     *str1 = NULL;
  87. }
  88.  
  89. /*
  90.  * strncat - cat a substring of up to N characters
  91.  */
  92. strncat(str1, str2, n)
  93. char *str1, *str2;
  94. unsigned n;
  95. {
  96.     while (*str1++)
  97.         ;
  98.     strncpy(str1 - 1, str2, n);
  99. }
  100.  
  101. /*
  102.  *    strncmp - compare a substring up to N characters long
  103.  */
  104. int strncmp(str1, str2, n)
  105. char *str1, *str2;
  106. unsigned n;
  107. {
  108. int i;
  109.     while (n--)
  110.         if (!*str1 && !*str2)
  111.             break;
  112.         else if (i = *str2++ - *str1++)
  113.             return(i);
  114.     return(0);
  115. }
  116.  
  117. /*
  118.  * strlower - map a string to lower case
  119.  */
  120. char *strlower(string)
  121. char *string;
  122. {
  123. char *x;
  124.  
  125.     x = string;
  126.     do
  127.         *x = tolower(*x);
  128.     while (*++x);
  129.     return string;
  130. }
  131.  
  132. /*
  133.  * strupper - map a string to upper case
  134.  */
  135. char *strupper(string)
  136. char *string;
  137. {
  138. char *x;
  139.  
  140.     x = string;
  141.     do
  142.         *x = toupper(*x);
  143.     while (*++x);
  144.     return string;
  145. }
  146.  
  147. /*
  148.  *    strindex - return the index of substr in str or error
  149.  */
  150. unsigned strindex(str, substr)
  151. char *str, *substr;
  152. {
  153. int i, len, limit;
  154. char save, *savloc;    /* not needed if using strncmp */
  155.  
  156.     len = strlen(substr);
  157.     limit = strlen(str) - len + 1;
  158.     for (i = 0; i < limit; i++) {
  159.         savloc = str + len;
  160.         save = *savloc;        /* so save the current value */
  161.         *savloc = '\0';        /* and then terminate the substring */
  162.         if (strcmp(str, substr) == 0) {
  163.             *savloc = save;    /* restore the saved character */
  164.             return(i);    /* and return the index */
  165.         }
  166.         *savloc = save;        /* restore the saved character */
  167.         str++;    /* otherwise, increment the start address and repeat */
  168.     }
  169.     return(ERROR);            /* not found, so return ERROR */
  170. }
  171.  
  172. /*
  173.  *    index - return the index of the first occurrence of C
  174.  *    in str or error if it is not found
  175.  */
  176. unsigned index(str, c)
  177. char *str, c;
  178. {
  179. int i;
  180.  
  181.     for (i = 0; *str; i++)
  182.         if (*str++ == c)
  183.             return(i);    /* found it */
  184.     return(ERROR);            /* did not find it */
  185. }
  186.  
  187. /*
  188.  * findline - this routine takes a BDS C file open for formatted I/O,
  189.  *    a buffer buf, and a string.  It returns, in buf, the first line
  190.  *    in the file that matches the string, up to either a tab, a space,
  191.  *    or a semicolon in the line from the file.
  192.  */
  193. int findline(file, line, pat)
  194. char *file, *line, *pat;
  195. {
  196. char *lp, *pp;
  197.  
  198.     while (fgets(line, file))
  199.         for (lp = line, pp = pat; ; pp++, lp++)
  200.             if (!*pp && index("\t :", *lp) != ERROR)
  201.                 return TRUE;
  202.             else if (*pp != *lp || !*pp)
  203.                 break;
  204.     return FALSE;
  205. }
  206.  
  207. /*
  208.  *    getdph - return the address of a disk parameter header
  209.  *    or error if the drive is out of the range 0-15
  210.  *    To guarentee the drive is configured, it is selected first
  211.  *    This is performed by bios call 9, but the Bios() function
  212.  *    can not be used, because it returns in <A> not <HL>
  213.  *    After the header is located, the default drive is reselected
  214.  */
  215. dph *getdph(drive)
  216. int drive;
  217. {
  218. unsigned *warmstart, seldsk, result;
  219. char current;
  220.  
  221.     current = bdos(GETCURRENT, 0);    /* save the current drive */
  222.     warmstart = 1;
  223.     seldsk = *warmstart + 24;    /* address of SELDSK routine */
  224.     if ((result = call(seldsk, 0, 0, drive, 0)) == 0)
  225.         return(ERROR);        /* invalid drive */
  226.     bios(SELDSK,current);        /* restore the original disk */
  227.     return(result);
  228. }
  229.  
  230. /*
  231.  *    extract - build a name string from an dir/fcb entry
  232.  *    and place it in name.  Return the user/drive number
  233.  */
  234. char extract(entry, name)
  235. dir *entry;
  236. char *name;
  237. {
  238. int i,n;
  239.  
  240.     n = 0;
  241.     for (i = 0; (i < 8) && ((name[n] = entry -> dir_name[i]) != ' '); i++)
  242.         n++;
  243.     name[n++] = '.';
  244.     for (i = 0; (i < 3) && ((name[n] = entry -> dir_type[i]) != ' '); i++)
  245.         n++;
  246.     name[n] = '\0';
  247.     return(entry -> dir_user);
  248. }
  249.  
  250. /*
  251.  * mputs - output the given string on the modem port
  252.  */
  253. mputs(string)
  254. char *string;
  255. {
  256.     while (*string)
  257.         mputc(*string++);
  258. }
  259.  
  260. /*
  261.  * mputc - output the given character on the modem port
  262.  */
  263. mputc(byte)
  264. char byte;
  265. {
  266.     while (!moready())
  267.         ;
  268.     MOD_TDATA(byte);
  269. }
  270.  
  271. /*
  272.  * moready - is the modem ready to have a character go to it?
  273.  */
  274. int moready()
  275. {
  276.     return MOD_TBE;
  277. }
  278.  
  279. /*
  280.  * mgetc - input a character from the modem port
  281.  */
  282. char mgetc()
  283. {
  284.     while (!miready())
  285.         ;
  286.     return MOD_RDATA;
  287. }
  288.  
  289. /*
  290.  * miready - is the modem ready to give me a character?
  291.  */
  292. int miready()
  293. {
  294.     return MOD_RDA;
  295. }
  296.  
  297. /*
  298.  * hayesput - output a command string to the hayes, and check the result
  299.  */
  300. char hayesput(string)
  301. char *string;
  302. {
  303.     mputs(string);
  304.     return hayesget();
  305. }
  306.  
  307. /*
  308.  * hayesget - get a result byte from the hayes smartmodem
  309.  */
  310. char hayesget()
  311. {
  312.     while (!miready())
  313.         ;
  314.     return mgetc();
  315. }
  316.  
  317. /*
  318.  *    PARSE - last modified [18 FEB 82]
  319.  *    General argument parsing routines for ARGC, and ARGV
  320.  *    Globarg and Posarg are available to the user. All other
  321.  *    routines are for internal use.  There are no externals.
  322.  */
  323.  
  324. /*
  325.  *    GLOBARG - parse and assign global flags to variables
  326.  *    return FALSE if there were errors in any of the arguments.
  327.  *    Fmt is a format string similar to the one used by printf
  328.  *    except a mandatory prefix and optional suffix can be specified.
  329.  *    The types supported are boolean, char, string, and number.
  330.  *    A default is required for each flag, and follows it in
  331.  *    the format string delimited by a colon.  The following is
  332.  *    an example for two flag, one boolean, and one numeric
  333.  *
  334.  *    ..."s|ymbols%b:false c|opies%n:1",&symbol,&copies...
  335.  */
  336. int globarg(argc,argv,formats,args)
  337. int argc;
  338. char *argv[],*formats[],args;
  339. {
  340. int i,flag,**results;
  341.  
  342.     results = &args;
  343.     argv[0] = 1;    /* argv[0] must be MANUALLY parsed beforehand */
  344.     if (_verify(formats,results) == ERROR)
  345.         return(FALSE);
  346.     while ((i = argv[0]) < argc) {
  347.         if ((flag = _parse(argc,argv,formats,results,TRUE)) == ERROR)
  348.             return(FALSE);
  349.         else if (!flag)
  350.             _incr(argc,argv);
  351.     }
  352.     argv[0] = 0;    /* signal first time to POSARG */
  353.     return(TRUE);
  354. }
  355.  
  356. /*
  357.  *    POSARG - parse and assign positional flags to variables
  358.  *    return a pointer to the next positional paramters, EOF,
  359.  *    or FALSE if there is an error parsing one of the arguments.
  360.  *    The formats and arguments are identical to those for GLOBARG
  361.  */
  362. int posarg(argc,argv,formats,args)
  363. int argc;
  364. char *argv[],*formats[],args;
  365. {
  366. int i,flag,**results;
  367.  
  368.     resu